package com.itheima.stock.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.itheima.stock.cache.Cache;
import com.itheima.stock.constant.RedisConstants;
import com.itheima.stock.dto.LoginDTO;
import com.itheima.stock.entity.SysUser;
import com.itheima.stock.enums.CodeEnum;
import com.itheima.stock.exception.Exceptions;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.service.UserService;
import com.itheima.stock.util.IdWorkers;
import com.itheima.stock.util.RedisKeyUtil;
import com.itheima.stock.vo.CaptchaVO;
import com.itheima.stock.vo.LoginVO;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * @author 28188
 */
@Service
public class UserServiceImpl implements UserService {

    private final Cache cache;
    private final IdWorkers idWorkers;
    private final SysUserMapper sysUserMapper;
    private final PasswordEncoder passwordEncoder;

    public UserServiceImpl(Cache cache, IdWorkers idWorkers, SysUserMapper sysUserMapper, PasswordEncoder passwordEncoder) {
        this.cache = cache;
        this.idWorkers = idWorkers;
        this.sysUserMapper = sysUserMapper;
        this.passwordEncoder = passwordEncoder;
    }

    /**
     * 获取验证码接口
     *
     * @return 验证码
     */
    @Override
    public CaptchaVO generateCaptcha() {
        // 生成4位随机验证码
        String captcha = RandomStringUtils.randomNumeric(4);
        // 生成redisKey后缀
        String keySuffix = idWorkers.nextStrId();
        // 生成redisKey
        String redisKey = RedisKeyUtil.generateKey(RedisConstants.CAPTCHA_PREFIX, keySuffix);
        // 缓存验证码
        cache.set(redisKey, captcha, RedisConstants.CAPTCHA_EXPIRE);
        return new CaptchaVO(captcha, redisKey);
    }

    /**
     * 登录接口
     *
     * @param loginDTO 登录参数
     * @return 登录结果
     */
    @Override
    public LoginVO login(LoginDTO loginDTO) {
        // 参数校验
        if (ObjectUtils.isEmpty(loginDTO) ||
                ObjectUtils.isEmpty(loginDTO.getUsername()) ||
                ObjectUtils.isEmpty(loginDTO.getPassword()) ||
                ObjectUtils.isEmpty(loginDTO.getCode()) ||
                ObjectUtils.isEmpty(loginDTO.getRkey())) {
            Exceptions.cast(CodeEnum.DATA_ERROR);
        }
        // 验证码校验
        String rkey = loginDTO.getRkey();
        String captchaInRedis = cache.get(rkey);
        boolean equals = StringUtils.equals(captchaInRedis, loginDTO.getCode());
        if (!equals) {
            Exceptions.cast(CodeEnum.SYSTEM_VERIFY_CODE_ERROR);
        }
        // 删除redis中的验证码
        cache.remove(rkey);
        // todo 登录时应该检验用户状态和是否被删除
        // 用户名密码校验
        SysUser user = sysUserMapper.selectByUsername(loginDTO.getUsername());
        if (ObjectUtils.isEmpty(user) || !passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            Exceptions.cast(CodeEnum.SYSTEM_PASSWORD_ERROR);
        }
        return new LoginVO(user.getId(), user.getUsername(), user.getNickName(), user.getPhone());
    }
}
